package net.valerijtimakov.homefinances.dao.storages.finances.mysql;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;

import net.valerijtimakov.homefinances.domain.common.DataItem;
import net.valerijtimakov.homefinances.domain.finances.TransferItem;
import net.valerijtimakov.homefinances.exceptions.AppExceptionWrongState;
import net.valerijtimakov.homefinances.exceptions.AppPersProviderException;
import net.valerijtimakov.homefinances.exceptions.AppPersistentException;
import net.valerijtimakov.homefinances.exceptions.wrongarg.AppExceptionNullArgument;
import net.valerijtimakov.homefinances.dao.storages.common.mysql.OperationItemsStorage;
import net.valerijtimakov.homefinances.dao.storages.common.mysql.query_builders.condition.WhereBuilder;
import net.valerijtimakov.homefinances.dao.storages.finances.ITransferStorage;
import net.valerijtimakov.homefinances.utils.Utils;

public class TransferStorage extends OperationItemsStorage implements ITransferStorage {
	
	protected String ammountFieldName = "ammount";
	protected String toAccountIdFieldName = "toAccountId";
	
	public TransferStorage(IMySqlProvider provider) throws AppExceptionWrongState {
		super(provider);
	}

	public Map<Long, TransferItem> filterTransfers(long[] fromAccountIds, final long[] toAccountIds, 
		long[] cathegoriesIds, long[] currenciesIds, Date addDateFrom, Date addDateTo, final float ammountFrom,
		final float ammountTo, String namePattern) throws AppPersProviderException, AppExceptionWrongState 
	{
		return super.filterCosts(fromAccountIds, cathegoriesIds, currenciesIds, addDateFrom, addDateTo, namePattern, 
			new FiltersAdditor() {
				public void addFilters(WhereBuilder whereBuilder) {
					whereBuilder.addIntervalCondBuilder(ammountFieldName, ammountFrom, ammountTo);
					whereBuilder.createListCondBuilder(toAccountIdFieldName, Long.class).importFieldValues(Utils.longArrToRef(toAccountIds));
				}
			});
	}

	public Map<Long, TransferItem> getAccountsTransfers(long... accountId) throws AppPersProviderException, AppExceptionWrongState {
		return super.getAccountOperations(accountId);
	}

	public Map<Long, TransferItem> getTransfers(long... id) throws AppPersProviderException, AppExceptionWrongState {
		return getItemsByIds(id);
	}

	public void addTransfer(TransferItem item) throws AppExceptionNullArgument, AppExceptionWrongState, AppPersistentException {
		addItem(item, "Не задан экземпляр перевода!", "Ошибка добавления перевода!");
	}

	public void removeTransfer(long id) throws AppPersProviderException, AppExceptionWrongState {
		delete(id);
	}

	public void updateTransfer(TransferItem item) throws AppPersProviderException, AppExceptionWrongState {
		update(item);
	}

	@Override
	protected String getTableName() {
		return "transrefs";
	}

	@Override
	protected DataItem createTempItem() {
		return new TransferItem();
	}

	@Override
	protected <T extends DataItem> void parse(ResultSet rs, T item) throws SQLException {
		super.parse(rs, item);
		TransferItem cItem = (TransferItem)item;
		cItem.setAmmount(rs.getFloat(ammountFieldName));
		cItem.setToAccountId(rs.getLong(toAccountIdFieldName));
	}
	
	@Override
	protected void initSelect() {
		super.initSelect();
		selectQuery.addField(ammountFieldName);
	}

	@Override
	protected <T extends DataItem> void addData(T item) {
		super.addData(item);
		TransferItem cItem = (TransferItem)item;
		insertQuery.setFieldValue(ammountFieldName, cItem.getAmmount());
		insertQuery.setFieldValue(toAccountIdFieldName, cItem.getAccountId());
	}

	@Override
	protected <T extends DataItem> void setUpdatedFields(T item) {
		super.setUpdatedFields(item);
		TransferItem cItem = (TransferItem)item;
		updateQuery.setFieldValue(ammountFieldName, cItem.getAmmount());
		updateQuery.setFieldValue(toAccountIdFieldName, cItem.getAccountId());
	}

}
